<?php


namespace coco;

//use coco\exception\ErrorException;
use coco\exception\Handle;
use coco\traits\Singleton;

/**
 * Class App
 * @package coco
 * @property-read string $coco_path
 * @property-read string $app_path
 * @property-read string $runtime_path
 * @property-read string $config_path
 * @property-read bool $is_cli
 */
class App
{
    use Singleton;

    protected $read_only;

    private function __construct(string $app_path, array $options = null)
    {
        $this->read_only = [
            'coco_path' => dirname(__FILE__) . '/',
            'app_path' => $app_path,
            'runtime_path' => $options['runtime_path'] ?? $app_path . '../runtime/',
            'config_path' => $options['config_path'] ?? $app_path . 'config/',
            'is_cli' => PHP_SAPI === 'cli',
        ];
        Tree::getInstance()->set('app', $this);
    }

    public function __get($name)
    {
        return $this->read_only[$name] ?? null;
    }

    protected static function init()
    {
        error_reporting(E_ALL);
        register_shutdown_function([self::class, 'appEnd']);
        set_exception_handler([Handle::getInstance(), 'report']);
        set_error_handler([Handle::getInstance(), 'error']);
    }

    public function run()
    {
        require_once $this->read_only['coco_path'] . '../functions.php';
        if (is_file($this->read_only['app_path'] . 'functions.php')) {
            require_once $this->read_only['app_path'] . 'functions.php';
        }
        self::init();
        try {
            Dispatch::getInstance()->run();
        } catch (\Throwable $e) {
            Handle::getInstance()->report($e);
        }
    }


    public static function appEnd()
    {
        Log::getInstance()->save();
    }
}